package com.gin.kotlin.no_gay_alliance.model

import android.os.Parcelable
import com.fasterxml.jackson.annotation.JsonIgnore
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils.Companion.SIMPLE_DATE_TIME_FORMATTER
import com.gin.nga.bbscode.BbsCodeNode
import com.gin.nga.enums.ForumType
import com.gin.nga.enums.MoreInfoType
import com.gin.nga.enums.PermissionBuffType
import com.gin.nga.enums.UserBuffType
import com.gin.nga.enums.status.AccountStatus
import com.gin.nga.response.user.Reputation
import com.gin.nga.response.user.UserBuff
import com.gin.nga.response.user.UserDetail
import com.gin.nga.response.user.UserRemark
import kotlinx.parcelize.Parcelize
import java.time.ZoneId
import java.time.ZonedDateTime

/**
 * 用户详情信息
 * @property userId 用户ID
 * @property username 用户名
 * @property regDatetime 注册时间
 * @property accountStatus 账号状态
 * @property postCount 发帖数
 * @property group 用户组和ID
 * @property adminForums 管理的版面
 * @property followed 是否已关注
 * @property followedCount 被关注数
 * @property ipLocation IP属地
 * @property honor 荣誉
 * @property totalAgreement 总赞数
 * @property giftReceived 年度获得礼物数
 * @property userForum 个人版面名称
 * @property email 邮箱
 * @property usernameChanged 用户名是否修改过
 * @property reputation 声望数据
 * @property buffs buff
 * @property remarks 备注
 * @property avatars 头像
 * @property medalId 徽章
 * @property prestige 威望
 * @property signature 签名
 * @property timestamp 当前数据获取的时间
 * @constructor
 */
@Parcelize
data class UserDetailModel(
    var userId: Long? = null,
    var username: String? = null,
    var regDatetime: ZonedDateTime? = null,
    var accountStatus: AccountStatus? = null,
    var postCount: Int? = null,
    var group: String? = null,
    var adminForums: List<ForumEntryModel>? = null,
    var followed: Boolean? = null,
    var followedCount: Int? = null,
    var ipLocation: String? = null,
    var honor: String? = null,
    var totalAgreement: Int? = null,
    var giftReceived: Int? = null,
    var userForum: String? = null,
    var email: String? = null,
    var usernameChanged: Boolean = false,
    var reputation: List<ReputationModel>? = null,
    var buffs: List<UserBuffModel>? = null,
    var remarks: List<UserRemarkModel>? = null,
    var avatars: List<String>? = null,
    var medalId: List<Int>? = null,
    var prestige: Int? = null,
    var signature: String? = null,
    var money: Int? = null,
    var timestamp: ZonedDateTime,
) : Parcelable {
    constructor() : this(timestamp = ZonedDateTime.now())

    @JsonIgnore
    fun getSignatureNode() = BbsCodeNode.parseContent(signature)

    constructor(userDetail: UserDetail, timestamp: ZonedDateTime) : this(
        timestamp = timestamp.withZoneSameInstant(ZoneId.systemDefault()),
        userId = userDetail.userId,
        username = userDetail.username,
        avatars = userDetail.getAvatars(),
        regDatetime = userDetail.regDatetime?.withZoneSameInstant(ZoneId.systemDefault()),
        accountStatus = userDetail.getAccountStatus(),
        postCount = userDetail.postCount,
        email = userDetail.email,
        group = "${userDetail.groupName}(${userDetail.groupId})",
        followed = userDetail.followed,
        followedCount = userDetail.followedCount,
        medalId = userDetail.medalId,
        ipLocation = userDetail.ipLocation,
        usernameChanged = userDetail.usernameChanged,
        signature = userDetail.signature,
        prestige = userDetail.prestige,
        totalAgreement = userDetail.moreInfo?.firstOrNull { it.getType() == MoreInfoType.AGREEMENT }?.data,
        giftReceived = userDetail.moreInfo?.firstOrNull { it.getType() == MoreInfoType.GIFT_RECEIVED }?.data,
        userForum = userDetail.userForum?.name,
        reputation = userDetail.reputations?.map { ReputationModel(it) },
        buffs = userDetail.buffs?.map { UserBuffModel(it) },
        remarks = userDetail.remark?.map { UserRemarkModel(it) },
        money = userDetail.money?.raw?.takeIf { it > 0 },
        adminForums = userDetail.adminForums?.map {
            ForumEntryModel(
                type = ForumType.FORUM,
                entryId = it.forumId!!,
                name = it.name!!,
                icon = it.getBigIconUrl()!!,
            )
        },
        honor = userDetail.getHonor()?.let {
            val name = it.name ?: ""
            val remark = it.remark ?: ""
            val time = it.timestamp?.let { t -> "自 ${SIMPLE_DATE_TIME_FORMATTER.format(t.withZoneSameInstant(ZoneId.systemDefault()))}" }
            "$name $remark $time"
        }
    )

    @Parcelize
    class ReputationModel(
        var name: String? = null,
        var value: Int? = null,
        var remark: String? = null,
    ) : Parcelable {
        constructor() : this(name = null)
        constructor(reputation: Reputation) : this(
            name = reputation.name,
            value = reputation.value,
            remark = reputation.remark,
        )
    }

    /**
     * 用户BUFF
     * @property id 存疑，可能是操作记录id
     * @property typeId buff类型id 已知类型的buff:  [UserBuffType]
     * @property fromUserId 释放buff的用户id
     * @property userId 被施加buff的用户id
     * @property start buff开始时间
     * @property end buff结束时间
     * @property extraData 额外数据，可能为版面id，头像buff id，或道具的subType等
     * @property data7 未知数据
     * @property description 描述
     * @property forumName 版面名称(如果是禁言buff)
     * @constructor
     */
    @Parcelize
    class UserBuffModel(
        var id: Long? = null,
        var typeId: Int? = null,
        var fromUserId: Long? = null,
        var userId: Long? = null,
        var start: ZonedDateTime? = null,
        var end: ZonedDateTime? = null,
        var extraData: Long? = null,
        var data7: Int? = null,
        var description: String? = null,
        var forumName: String? = null,
    ) : Parcelable {
        @JsonIgnore
        fun getType() = UserBuffType.find(typeId)

        /**
         * 当type为权限类型时，返回权限buff类型
         * @return PermissionBuffType?
         */
        @JsonIgnore
        fun getPermissionBuffType() = getType()?.takeIf { it == UserBuffType.PERMISSION }?.let { extraData?.let { id -> PermissionBuffType.findById(id.toInt()) } }


        constructor() : this(userId = null)
        constructor(buff: UserBuff) : this(
            id = buff.id,
            typeId = buff.typeId,
            fromUserId = buff.fromUserId,
            userId = buff.userId,
            start = buff.start,
            end = buff.end,
            extraData = buff.extraData,
            data7 = buff.data7,
            description = buff.description,
            forumName = buff.getForumName(),
        )
    }

    /**
     * 用户备注
     * @property id 备注ID
     * @property fromUserId 添加备注的用户id
     * @property timestamp 添加备注的时间
     * @property public 是否为公开备注
     * @property text 备注内容
     * @constructor
     */
    @Parcelize
    class UserRemarkModel(
        var id: Long? = null,
        var fromUserId: Long? = null,
        var timestamp: ZonedDateTime? = null,
        var public: Boolean? = null,
        var text: String? = null,
    ) : Parcelable {
        constructor() : this(id = null)
        constructor(userRemark: UserRemark) : this(
            id = userRemark.id,
            fromUserId = userRemark.fromUserId,
            timestamp = userRemark.timestamp?.withZoneSameInstant(ZoneId.systemDefault()),
            public = userRemark.public,
            text = userRemark.text,
        )
    }


    companion object

}